<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        
        
        
        <link rel="shortcut icon" href="../img/favicon.ico">

	<title>接入指南 - AIOS技术支持文档</title>

        <link href="../css/bootstrap-custom.min.css" rel="stylesheet">
        <link href="../css/font-awesome-4.0.3.css" rel="stylesheet">
        <link rel="stylesheet" href="../css/highlight.css">
        <link href="../css/base.css" rel="stylesheet">

        <!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries -->
        <!--[if lt IE 9]>
            <script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
            <script src="https://oss.maxcdn.com/libs/respond.js/1.3.0/respond.min.js"></script>
        <![endif]-->

        
    </head>

    <body>

        <div class="navbar navbar-default navbar-fixed-top" role="navigation">
    <div class="container">

        <!-- Collapsed navigation -->
        <div class="navbar-header">
            <!-- Expander button -->
            <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
                <span class="sr-only">Toggle navigation</span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
            </button>

            <!-- Main title -->
            <a class="navbar-brand" href="..">AIOS技术支持文档</a>
        </div>

        <!-- Expanded navigation -->
        <div class="navbar-collapse collapse">
            <!-- Main navigation -->
            <ul class="nav navbar-nav">
            
            
                <li >
                    <a href="..">首页</a>
                </li>
            
            
            
                <li >
                    <a href="../intro/">功能介绍</a>
                </li>
            
            
            
                <li class="active">
                    <a href="./">接入指南</a>
                </li>
            
            
            
                <li >
                    <a href="../question/">常见问题</a>
                </li>
            
            
            
                <li >
                    <a href="../changelog/">更新日志</a>
                </li>
            
            
            </ul>

            <!-- Search, Navigation and Repo links -->
            <ul class="nav navbar-nav navbar-right">
                <li>
                    <a href="#" data-toggle="modal" data-target="#mkdocs_search_modal">
                        <i class="fa fa-search"></i> Search
                    </a>
                </li>
                <li >
                    <a rel="next" href="../intro/">
                        <i class="fa fa-arrow-left"></i> Previous
                    </a>
                </li>
                <li >
                    <a rel="prev" href="../question/">
                        Next <i class="fa fa-arrow-right"></i>
                    </a>
                </li>
                
            </ul>
        </div>
    </div>
</div>

        <div class="container">
            <div class="col-md-3"><div class="bs-sidebar hidden-print affix well" role="complementary">
    <ul class="nav bs-sidenav">
    
        <li class="main active"><a href="#aios30">AIOS3.0 开发指导文档</a></li>
        
            <li><a href="#_1">一、调试步骤</a></li>
        
            <li><a href="#_2">二、电话</a></li>
        
            <li><a href="#_3">三、导航</a></li>
        
            <li><a href="#_4">四、微信</a></li>
        
            <li><a href="#_5">五、音乐和电台</a></li>
        
            <li><a href="#_6">六、设置</a></li>
        
            <li><a href="#_7">七、静态定制</a></li>
        
            <li><a href="#_8">八、动态定制</a></li>
        
            <li><a href="#ui">九、UI</a></li>
        
            <li><a href="#_9">十、自定义语音播报</a></li>
        
            <li><a href="#_10">十一、系统控制</a></li>
        
            <li><a href="#_11">十二、状态</a></li>
        
            <li><a href="#_12">十三、快捷唤醒</a></li>
        
    
    </ul>
</div></div>
            <div class="col-md-9" role="main">

<h2 id="aios30">AIOS3.0 开发指导文档</h2>
<table>
<thead>
<tr>
<th align="right">作者：</th>
<th align="left">开发组</th>
<th align="right">日期：</th>
<th align="left">2016-07-08</th>
</tr>
</thead>
<tbody>
<tr>
<td align="right">审核：</td>
<td align="left">王 强</td>
<td align="right">日期：</td>
<td align="left">2016-08-26</td>
</tr>
</tbody>
</table>
<p>变更记录</p>
<table>
<thead>
<tr>
<th align="center">AIOS版本</th>
<th align="center">日期</th>
<th align="center">变更说明</th>
<th align="center">作者</th>
</tr>
</thead>
<tbody>
<tr>
<td align="center">2.1.0</td>
<td align="center">2016-7-8</td>
<td align="center">初始版本</td>
<td align="center">袁月明</td>
</tr>
<tr>
<td align="center">3.0.2</td>
<td align="center">2016-7-14</td>
<td align="center">修改完善</td>
<td align="center">袁月明</td>
</tr>
<tr>
<td align="center">3.0.2</td>
<td align="center">2016-7-16</td>
<td align="center">完善SDK说明</td>
<td align="center">刘嵘</td>
</tr>
<tr>
<td align="center">3.0.8</td>
<td align="center">2016-7-29</td>
<td align="center">新增接口</td>
<td align="center">刘嵘</td>
</tr>
<tr>
<td align="center">3.0.9</td>
<td align="center">2016-8-6</td>
<td align="center">新增接口，<em>aios-bridge</em> 应用必须安装</td>
<td align="center">刘嵘</td>
</tr>
<tr>
<td align="center">3.0.10</td>
<td align="center">2016-8-11</td>
<td align="center">新增路况 <em>UI</em> 接口</td>
<td align="center">刘嵘</td>
</tr>
<tr>
<td align="center">3.0.11</td>
<td align="center">2016-8-20</td>
<td align="center">新增音乐和电台说明</td>
<td align="center">袁月明</td>
</tr>
<tr>
<td align="center">3.0.12</td>
<td align="center">2016-8-26</td>
<td align="center">调整 <em>AIOS</em> 与 <em>SDK</em> 的关系</td>
<td align="center">刘嵘</td>
</tr>
</tbody>
</table>
<h3 id="_1">一、调试步骤</h3>
<ul>
<li>安装：<br />
 将 <strong><em>aios-daemon.apk</em></strong>、<strong><em>aios-adapter.apk</em></strong>、<strong><em>~~aios-bridge.apk~~</em></strong>(非必须) 和 <strong><em>aios-wechat.apk</em></strong> <em>push</em> 到 <em>/system/app</em>，并解压 <strong><em>aios-daemon.apk</em></strong> 和 <strong><em>aios-wechat.apk</em></strong>，将相关 <em>so</em> 文件（区分 <em>armeabi</em> 和 <em>x86</em>） <em>push</em> 到  <em>/system/lib</em> 。<br />
<em>Android 5.0+</em> 需根据具体情况作出相应调整。<em>push</em> 完成后，重启机器便能够正常使用 <em>AIOS</em>。如果机器之前已安装过其他版本的 <em>AIOS</em> ，建议在 <em>push</em> 完成后恢复出厂设置。</li>
</ul>
<h4 id="i-aiosforcarsdk-aios">I .集成 <em>AIOSForCarSDK</em> ，定制 <em>AIOS</em></h4>
<pre><code class="java">//SDK初始化
AIOSForCarSDK#initialize(Application)
AIOSForCarSDK#initialize(Application, AIOSReadyListener)
</code></pre>

<p>在初始化 <em>AIOSForCarSDK</em> 时，直接调用上述方法便可以完成 <em>AIOSForCarSDK</em> 的集成。你可以在 <em>AIOSReadyListener</em> 回调做一些初始化操作，包括但不限于：</p>
<ol>
<li>定制默认地图、语音资源、对话风格、自定义命令、自定义快捷唤醒词等；  </li>
<li>监听 <em>AIOS</em> 状态、录音机状态、 <em>TTS</em> 播报状态等；  </li>
<li>在启动后提供已集成 <em>AIOSForCarSDK</em> 的普通应用（蓝牙电话、接入音乐等）的基本参数，以便在这些应用未打开时 <em>AIOS</em> 能够调起并完成相应功能。
 <em>AIOS</em> 开发包中的 <em>aios-bridge.apk</em> 作为演示程序提供，您可以从开发包中获取到对应的源代码直接作为骨架进行二次开发；也可以自行按照以下步骤实现：</li>
</ol>
<p>具体需要以下几个步骤：</p>
<ol>
<li>申请权限 <br />
<em>AIOS</em> 内部通讯需要申请网络权限，请在 <em>Androidmanifest.xml</em>  添加以下权限：</li>
</ol>
<pre><code class="xml">&lt; uses-permission android:name=&quot;android.permission.INTERNET&quot; /&gt;
</code></pre>

<ol>
<li>
<p>~~授权~~<br />
~~将授权文件复制入项目资源文件夹下；（授权文件已移除）~~</p>
</li>
<li>
<p>定制领域开关<br />
参照 <em>aios-bridge\src\main\assets\configs</em> 定制领域并复制入项目资源文件夹下；</p>
</li>
<li>
<p>初始化应用<br />
将 <em>aios-sdk.jar</em> 引入项目，并在 <em>Application</em> 子类的 <em>onCreate（）</em> 方法中完成初始化 。示例代码如下：</p>
</li>
</ol>
<pre><code class="java">public class BridgeApplication extends Application {
    private static final String TAG = &quot;Bridge - BridgeApplication&quot;;
    private static Context mContext;

    public static Context getContext() {
        if (mContext == null) {
            throw new RuntimeException(&quot;Unknown Error&quot;);
        }
        return mContext;
    }

    public static BridgeApplication getApplication() {
        if (mContext == null) {
            throw new RuntimeException(&quot;Unknown Error&quot;);
        }
        return (BridgeApplication) mContext;
    }

    @Override
    public void onCreate() {
        super.onCreate();

        mContext = this;
        AIOSForCarSDK.initialize(this, new AIOSReadyListener() {
            @Override
            public void onAIOSReady() {
                AILog.d(TAG, &quot;On aios ready...&quot;);
                //使原生快捷唤醒词生效
                AIOSCustomizeManager.getInstance().setNativeShortcutWakeupsEnabled(true);
                //定制录音机
                AIOSCustomizeManager.getInstance().customizeRecorder(
                        PreferenceUtil.getBoolean(mContext, PreferenceUtil.IS_AEC_ENABLED, false),
                        PreferenceUtil.getBoolean(mContext, PreferenceUtil.IS_INTERRUPT_ENABLED, false), false
                );

                //定制主唤醒词
                List&lt;MajorWakeup&gt; majorWakeups= new ArrayList&lt;MajorWakeup&gt;();
                majorWakeups.add(new MajorWakeup(&quot;你好小驰&quot;, &quot;ni hao xiao chi&quot;, 0.13f));
                AIOSCustomizeManager.getInstance().setMajorWakeup(majorWakeups);

                //定制悬浮窗为全屏
                WindowManager.LayoutParams layoutParams = AIOSUIManager.getInstance().obtainLayoutParams();
                layoutParams.type = WindowManager.LayoutParams.TYPE_PHONE;
                layoutParams.flags = WindowManager.LayoutParams.FLAG_FULLSCREEN | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
                AIOSUIManager.getInstance().setLayoutParams(layoutParams);

                //设置音频管理监听器，请实现或者使用以下监听器
                AIOSAudioManager.getInstance().registerAudioListener(new BridgeAudioListener());
                //如果静态注册了自定义命令，请注册以下监听器
                AIOSCustomizeManager.getInstance().registerCustomizeListener(customizeListener);
            }
        });
    }

    AIOSCustomizeListener customizeListener = new AIOSCustomizeListener() {
        @Override
        public void onCommandEffect(@NonNull String command) {
            AILog.i(TAG, &quot;Command effect: &quot;+command);
        }

        @Override
        public void onShortcutWakeUp(@NonNull String pinyin) {
            AILog.i(TAG, &quot;Short cut wakeup:&quot;+pinyin);
        }
    };
}
</code></pre>

<ol>
<li>为应用添加自启属性并且接收开机广播：  </li>
</ol>
<pre><code class="java">&lt;application
        android:name=&quot;.BridgeApplication&quot;
        android:allowBackup=&quot;true&quot;
        android:icon=&quot;@drawable/ic_launcher&quot;
        android:label=&quot;@string/app_name&quot;
        android:supportsRtl=&quot;true&quot;
        android:persistent=&quot;true&quot; //添加这个参数以便能够自启动
        android:theme=&quot;@style/AppTheme&quot;&gt;

         &lt;receiver
            android:name=&quot;.receiver.BridgeReceiver&quot;
            android:enabled=&quot;true&quot;
            android:exported=&quot;true&quot; &gt;
            &lt;intent-filter&gt;
                //接收以下两个广播，以便能够开机启动
                &lt;action android:name=&quot;android.intent.action.BOOT_COMPLETED&quot; /&gt;
                &lt;action android:name=&quot;android.intent.action.QUICKBOOT_POWERON&quot; /&gt;
            &lt;/intent-filter&gt;
        &lt;/receiver&gt;
&lt;/application&gt;
</code></pre>

<p><em>BridgeReceiver</em> 类如下：</p>
<pre><code class="java">public class BridgeReceiver extends BroadcastReceiver {
    private static final String TAG = &quot;Bridge - BridgeReceiver&quot;;

    @Override
    public void onReceive(Context context, Intent intent) {
        AILog.i(TAG, &quot;onReceive - &quot; + intent.getAction());

        //开启广播可不处理，只为拉起应用
    }
}
</code></pre>

<ol>
<li>在合适的代码块中进行自定义命令、自定义快捷唤醒、修改默认设置项等操作。</li>
</ol>
<h4 id="ii-aiosforcarsdk">II .集成 <em>AIOSForCarSDK</em> ，接入新应用</h4>
<pre><code class="java">//初始化普通应用
AIOSForCarSDK#initialize(Application)
AIOSForCarSDK#initialize(Application, AIOSReadyListener)
</code></pre>

<p>初始化普通应用使用上述两个方法中的一种即可，通常用于接入新的地图、新的音乐或者蓝牙电话应用等。</p>
<h5 id="1">1. 申请权限</h5>
<p><em>AIOS</em> 内部通讯需要申请网络权限，请在 <em>Androidmanifest.xml</em>  添加以下权限：</p>
<pre><code class="xml">&lt; uses-permission android:name=&quot;android.permission.INTERNET&quot; /&gt;
</code></pre>

<h5 id="2">2. 初始化</h5>
<p>将 <em>aios-sdk.jar</em> 引入项目，并在 <em>Application</em> 子类的 <em>onCreate（）</em> 方法中完成初始化 。示例代码如下：</p>
<pre><code>public class NormalApplication extends Application{
         @Override
    public void onCreate() {
        super.onCreate();

        AIOSForCarSDK.initialize(this, new AIOSReadyListener() {
            @Override
            public void onAIOSReady() {
                //完成初始化、修改设置、添加自定义命令、添加自定义快捷唤醒词等操作
            }
        });
    }
}
</code></pre>

<h3 id="_2">二、电话</h3>
<p>如果需要对接蓝牙电话应用，您可以通过接入 <em>aios-sdk.jar</em> 来实现。<em>AIOS</em> 只关心电话状态改变，您只需要在来电时将联系人名称与电话传递给 <em>AIOS</em>，在去电时接收联系人名称与电话并开始拨号。同时实时共享蓝牙连接状态、电话接通、拒绝与挂断状态。</p>
<h4 id="i">I  .主动操作</h4>
<ol>
<li><span id="phone_bt">同步蓝牙状态</span><br />
电话的所有操作都应在蓝牙连接时进行。您需要使用以下接口同步蓝牙状态给 <em>AIOS</em>：</li>
</ol>
<pre><code class="java">//更新蓝牙状态
public void AIOSPhoneManager#setBTStatus(boolean isConnected)
</code></pre>

<ol>
<li><span id="phone_sync">同步联系人、清空联系人</span><br />
为了保障联系人名称的识别度，您可以将联系人信息同步到 <em>AIOS</em>：</li>
</ol>
<pre><code class="java">//同步联系人
public void AIOSPhoneManager#syncContacts(List&lt;ContactInfo&gt; list)；
//清空联系人
public void AIOSPhoneManager#clearContacts()；
</code></pre>

<ol>
<li><span id="phone_in_out">发起来电、发起去电</span><br />
发起来电，将联系人与号码发送给AIOS，AIOS会语音询问车主接听还是拒绝；使用手机/车机/后视镜蓝牙APP拨打电话时，发起去电令AIOS停止录音，释放MIC。</li>
</ol>
<pre><code class="java">//发起来电
public void AIOSPhoneManager#incomingCallRing(String name, String number);
//发起去电
public void AIOSPhoneManager#outgoingCallRing() ;
</code></pre>

<ol>
<li><span id="phone_offhook_end">接通电话、挂断电话</span><br />
无论是来电还是去电，在电话接通与电话挂断时都需要通知AIOS，AIOS会根据当前状态决定是否开启录音，是否能够唤醒，是否能够占用MIC等细节。</li>
</ol>
<pre><code class="java">//接通电话
public void AIOSPhoneManager#callOffhook();
//挂断电话
public void AIOSPhoneManager#callEnd();
</code></pre>

<ol>
<li><span id="phone_ui">设置是否显示来电UI</span><br />
您可以定制AIOS是否显示来电UI：</li>
</ol>
<pre><code>//是否显示来电UI
public void AIOSPhoneManager#setShowIncomingUI(boolean isShow);
</code></pre>

<h4 id="ii">II .<span id="phone_register">被动回调</span></h4>
<p>回调接口主要是接听电话与拒绝电话，附带去电、获取蓝牙状态与联系人同步结果回调。细节请见：</p>
<pre><code class="java">com.aispeech.aios.sdk.listener.AIOSPhoneListener
</code></pre>

<h4 id="iii">III.接入蓝牙电话</h4>
<ol>
<li><a href="#phone_register">实现电话监听器</a>   </li>
<li>注册电话监听器<br />
与其他监听器注册操作一样，调用管理类方法即可：</li>
</ol>
<pre><code class="java">AIOSPhoneManager.getInstance().registerPhoneListener(phoneListener);
</code></pre>

<ol>
<li>接收蓝牙电话应用调起广播，以便在应用未启动时AIOS能够正常调起应用并完成操作。请注册广播接收器，蓝牙电话应用调起广播的 <em>action</em> 如下：</li>
</ol>
<pre><code>&lt;action android:name=&quot;aios.intent.action.phone.BOOT&quot;/&gt;
</code></pre>

<p>请根据具体情况接收该广播并转到蓝牙电话监听器注册流程上，以便AIOS收到注册消息后继续执行操作。</p>
<ol>
<li><a href="#phone_sync">同步联系人</a>   </li>
<li><a href="#phone_ui">定制是否显示来电UI</a>  </li>
<li><a href="#phone_bt">实时更新蓝牙状态</a>  </li>
<li><a href="#phone_in_out">来电与去电时，通知AIOS更新状态</a>  </li>
<li><a href="#phone_offhook_end">挂断电话、接通电话时，通知AIOS更新状态</a><br />
无论是对方还是我方，只要挂断电话、接通电话时，都需要通知AIOS更新状态  </li>
<li>注销电话监听器，清空数据
当不再使用蓝牙应用时，请注销电话监听器，视具体情况决定是否清空联系人：</li>
</ol>
<pre><code>//注销电话监听器
AIOSPhoneManager.getInstance().unregisterPhoneListener();
</code></pre>

<h3 id="_3">三、导航</h3>
<h4 id="i-aios">I .使用 AIOS 原生支持的地图应用</h4>
<p><em>AIOS</em> 目前支持的地图包括：高德地图车机版、高德地图车镜版、高德地图、百度地图、百度导航、腾讯地图车机版、凯立德地图（定制版）、图吧地图（定制版）。直接安装相应地图（非定制版）即可语音操控“导航去XX”、“找一下附近的XX”和“查看我的位置”等功能，同时我们也提供了大量的快捷唤醒词，您可以在导航中使用快捷唤醒词直接控制地图应用。</p>
<h4 id="ii_1">II.接入新地图</h4>
<p>当需要使用 <em>AIOS</em> 控制其他地图时，您可以通过接入 <em>aios-sdk.jar</em> 来实现。接入新地图，需要 <em>SDK</em> 集成者提供新地图的一些基础信息以帮助 <em>AIOS</em> 正确使用新地图。同时考虑到火星坐标系<em>（GCJ-02）</em>在国内的支持情况，搜索附近与搜索目的地等接口返回的位置信息均使用火星坐标系<em>（GCJ-02）</em>标识，请知悉。</p>
<ol>
<li>填写地图信息<br />
地图信息中的路径规划策略，目前只支持四种策略，您可以在 <em>MapProperty.OptimizeStrategy</em>  类中查看到。以接入腾讯地图为例，首先创建地图信息类对象：</li>
</ol>
<pre><code class="java">//设置新地图信息
MapInfo tencentMap = new MapInfo(&quot;腾讯地图&quot;,&quot;com.tencent.map&quot;);
//设置地图是否支持退出导航，默认false
tencentMap.setCancelNaviSupported(true);
//设置地图是否支持查看全程，默认false
tencentMap.setOverviewSupported(true);
//设置地图是否支持地图缩放，默认false
tencentMap.setZoomSupported(true);
//设置地图支持的路径规划策略，默认都不支持。目前AIOS只支持SupportedRoutePlanningStrategy下定义的四种规划策略
tencentMap.setSupportedRoutePlanningStrategy(MapProperty.SupportedRoutePlanningStrategy.DRIVING_AVOID_CONGESTION , MapProperty.SupportedRoutePlanningStrategy.DRIVING_SAVE_MONEY);

//添加地图，添加多个地图请见setLocalMapsInfo(List&lt;MapInfo&gt;)
AIOSMapManager.getInstance().setLocalMapInfo(tencentMap);
</code></pre>

<ol>
<li>添加地图<br />
将地图信息通过 <em>SDK</em> 传入 <em>AIOS</em>，<em>SDK</em> 提供了四种接口，您可以根据实际情况任意选取，具体参数信息可参考 <em>com.aispeech.aios.sdk.manager.AIOSMapManager</em>：</li>
</ol>
<pre><code class="java">//添加单款地图
public boolean AIOSMapManager#setLocalMapInfo(@NonNull MapInfo mapInfo)
//添加单款地图，并决定是否清空之前的地图缓存信息（默认不清空）
public boolean AIOSMapManager#setLocalMapInfo(@NonNull MapInfo mapInfo, boolean isCleanCache)
//添加多款地图
public boolean AIOSMapManager#setLocalMapsInfo(@NonNull List&lt;MapInfo&gt; mapInfos)
//添加多款地图，并决定是否清空之前的地图缓存信息（默认不清空）
public boolean AIOSMapManager#setLocalMapsInfo(@NonNull List&lt;MapInfo&gt; mapInfos, boolean isCleanCache)
</code></pre>

<ol>
<li>实现地图监听器<br />
为了正常使用上步中新接入的地图，需要在设备上安装该地图并在 <em>AIOS</em> 的设置页面中将其选为默认地图，完成这些操作后，导航领域的语音命令都将会转到 <em>SDK</em> 处理。此时需要开发者实现如下接口，以便新接入的地图能够处理这些语音命令：</li>
</ol>
<pre><code class="java">com.aispeech.aios.sdk.listener.AIOSMapListener
</code></pre>

<p>需要注意的是，<em>AIOS</em> 在导航领域中均采用火星坐标系<em>（GCJ-02）</em>。如果新地图使用其他坐标系，谨记先行转换再使用。</p>
<ol>
<li>注册地图监听器
注册地图监听器，以便在需要时回调：</li>
</ol>
<pre><code class="java">AIOSMapManager.getInstance().setMapListener(mapListener);
</code></pre>

<ol>
<li>接收地图应用调起广播，以便在应用未启动时AIOS能够正常调起应用并完成操作。请注册广播接收器，地图应用调起广播的 <em>action</em> 如下：</li>
</ol>
<pre><code class="xml">&lt;action android:name=&quot;aios.intent.action.map.BOOT&quot;/&gt;
</code></pre>

<p>请根据具体情况接收该广播并转到地图监听器注册流程上，以便AIOS收到注册消息后继续执行操作。</p>
<ol>
<li>注销地图监听器
当不需要使用新地图时，您可以清空地图信息并注销地图监听器，使AIOS恢复到原状：</li>
</ol>
<pre><code class="java">//清空原有的地图信息，请根据具体情况决定是否调用
AIOSMapManager.getInstance().cleanMapInfo();
//注销地图监听器
AIOSMapManager.getInstance().unregisterMapListener();
</code></pre>

<h3 id="_4">四、微信</h3>
<p>请先安装 <em>AIOS</em> 微信，按照提示扫描二维码，登陆微信即可语音操控 “我要发微信给XX”、“回复微信”以及在收到好友发来的位置信息时直接导航到该位置。通过关注 “<strong>车语互联</strong>“ 公众号 <em>( <strong>aiosforcar</strong> )</em> 绑定设备，后续将会提供车辆定位、行驶轨迹、防盗提醒等更加丰富的功能。
微信群消息默认不播报，只有当 @到用户 的时候才会播报。用户说“回复微信”，录音时长最长支持 <em>1min</em>，若检测到您 <em>5s</em> 未说话， 微信会进入 <em>3s</em> 倒计时，到时自动发送。如需提前结束，可说 “完毕完毕”立即发送。倒计时期间和录音阶段说“取消取消”则微信取消发送。</p>
<h3 id="_5">五、音乐和电台</h3>
<h4 id="i-aios_1">I .使用AIOS原生支持的音乐</h4>
<p><em>AIOS</em> 原生支持的音乐应用包括：酷我音乐、喜马拉雅<em>FM</em>、车悦宝。严格意义上来讲，喜马拉雅<em>FM</em>只能处理音频控制命令，音乐搜索功能由酷我音乐完成，车悦宝两者兼之。
使用原生支持的音乐应用，您可以根据歌名、歌手搜索想听的音乐，可以通过语音改变播放模式等。<em>AIOS</em> 默认在启动时会扫描本地音乐文件，您可以通过 <em>SDK</em> 来开启或者关闭扫描功能：</p>
<pre><code class="java">//是否开启本地音乐扫描
public void AIOSMusicManager#setAIOSScanMusic(boolean enable)
</code></pre>

<p>如果关闭了本地音乐扫描，歌曲与歌手的识别度将会有所下降。为了提升语音识别的准确度，您可以将需要识别的歌曲信息同步到 <em>AIOS</em>：</p>
<pre><code class="java">//同步本地音乐列表
public void AIOSMusicManager#syncLocalMusicList(List&lt;LocalMusic&gt; list);
</code></pre>

<h4 id="ii_2">II.接入新音乐</h4>
<p>如果需要接入其他的音乐应用，您可以通过接入 <em>aios-sdk.jar</em> 来实现。目前 <em>AIOS</em> 暂时只支持接入一款音乐，与接入地图类似，接入操作同样需要集成方提供音乐基本信息。</p>
<ol>
<li>设置新音乐基本信息</li>
</ol>
<pre><code class="java">//设置新音乐基本信息
public void AIOSMusicManager#setLocalMusicInfo(@NonNull String musicName, @NonNull String musicPackageName)
</code></pre>

<p>接入新音乐需要提供的基本信息较为简单，只需要给出音乐名称与音乐包名。请确保音乐包名正确，在处理音乐控制命令时十分依赖包名。</p>
<ol>
<li>实现音乐监听器</li>
</ol>
<pre><code class="java">com.aispeech.aios.sdk.listener.AIOSMusicListener
</code></pre>

<p>音乐监听器包含了 <em>AIOS</em> 目前所有的音频控制命令回调与音乐搜索命令回调。如果接入新音乐，那么音乐搜索操作将会依赖新音乐完成，所以请务必在实现 <em>AIOSMusicListener#onSearch()</em> 时，将搜索结果提交给 <em>AIOS</em>，否则 <em>AIOS</em> 将会判定音乐搜索超时。结果提交方法如下：</p>
<pre><code class="java">//提交搜索结果
public void AIOSMusicManager#postMusicSearchResult(List&lt;Music&gt; musics, int keyIndex)；
</code></pre>

<ol>
<li>注册音乐监听器
注册音乐监听器，以便在需要时回调：</li>
</ol>
<pre><code class="java">AIOSMusicManager.getInstance().registerMusicListener(musicListenr);
</code></pre>

<p>一旦音乐监听器注册成功，音乐的搜索命令将全部转到当前应用处理。接入的音乐应用也将开始参与音乐控制命令的竞争。</p>
<ol>
<li>接收音乐应用调起广播，以便在应用未启动时AIOS能够正常调起应用并完成操作。请注册广播接收器，音乐应用调起广播的 <em>action</em> 如下：</li>
</ol>
<pre><code class="java">&lt;action android:name=&quot;aios.intent.action.music.BOOT&quot;/&gt;
</code></pre>

<p>请根据具体情况接收该广播并转到音乐监听器注册流程上，以便AIOS收到注册消息后继续执行操作。</p>
<ol>
<li>实时更新新音乐播放状态
无论是否接入新音乐，<em>AIOS</em> 音频控制命令（如上一首、继续播放等）都由音乐应用竞争。为了保障接入的音乐应用能够正常参与竞争，需要您在音乐应用的状态改变时，实时通知 <em>AIOS</em>，具体方法如下：</li>
</ol>
<pre><code class="java">//如果状态成功改变，调用接口通知AIOS
public void AIOSMusicManager#setPlayState(int state)
</code></pre>

<p>如果您接入第三方音乐应用，可查看该应用是否有相应的播放状态回调。</p>
<ol>
<li>注销音乐监听器
当不需要再使用接入的音乐应用时，您可以通过清空音乐信息并注销音乐监听器来使 <em>AIOS</em> 恢复原状：</li>
</ol>
<pre><code class="java">//清除音乐应用信息
AIOSMusicManager.getInstance().cleanLocalMusicInfo();
//注销音乐监听器
AIOSMusicManager.getInstance().unregisterMusicListener();
</code></pre>

<h4 id="iii_1">III.定制音乐流程</h4>
<p>目前支持纯搜歌名时，定制是否显示结果列表（车悦宝不支持显示结果列表），相应的接口为：</p>
<pre><code class="java">//设置纯搜歌名时是否显示结果列表
AIOSMusicManager#setDisplayListEnabled(boolean enable)
</code></pre>

<h3 id="_6">六、设置</h3>
<blockquote>
<p>对话风格支持对话模式（默认）和经典模式两种
语音资源支持林志玲声音（默认）和郭德纲声音两种</p>
</blockquote>
<p>如果需要修改包括：对话风格、语音资源与默认地图在内的设置，可通过集成 <em>aios-sdk.jar</em> 实现。同时，您也可以通过注册设置监听器来监听设置项的修改。</p>
<ol>
<li>按照自身需求，定制设置项默认内容  </li>
</ol>
<pre><code class="java">//设置默认对话风格，参数取值见com.aispeech.aios.common.property.SettingProperty.DialogueProperty
public void AIOSSettingManager#setDialogueStyle(int dialogueStyle);

//设置默认语音资源，参数取值见com.aispeech.aios.common.property.SettingProperty.TtsResProperty
public void AIOSSettingManager#setTtsRes(@NonNull String ttsRes)

//设置默认地图，参数取值可见com.aispeech.aios.common.config.PkgName.MapPkgName
public void AIOSSettingManager#setDefaultMap(@NonNull String packageName)
</code></pre>

<p>AIOS原生支持的地图，可以在上述MapPkgName类中获取到其包名。如需设置新接入的地图为默认地图，请直接将该地图包名传递AIOS。</p>
<ol>
<li>实现并注册设置监听器<br />
如果需要监听设置项的变化，您可以实现以下监听器：</li>
</ol>
<pre><code class="java">com.aispeech.aios.sdk.listener.AIOSSettingListener
</code></pre>

<p>并注册设置监听器：</p>
<pre><code class="java">//注册设置监听器
AIOSSettingManager.getInstance().registerSettingListener(settingListener);
</code></pre>

<h3 id="_7">七、静态定制</h3>
<p><em>AIOS</em> 在第一次启动之前您也可以配置其属性，这些属性包括但不限于：语音启动语、启动延时时间、语音启动语延时时间、静态注册自定义命令与领域开关等参数，后续会持续增加。</p>
<h4 id="i_1">I.预定义属性</h4>
<p>如果您需要在 <em>AIOS</em> 第一次启动之前定制其属性，可以将属性预置到 <em>/system/etc/aios/aios.properties</em> 下，您也可以在 <em>aios-bridge</em> 源码项目的 <em>assets</em> 目录中找到。文件内容如下：</p>
<pre><code class="sh">#语音启动语
launch_tips = 语音已启动，您可以使用你好小驰来唤醒

#每次启动前的延迟时间
delay_in_boot = 2000

#播报语音启动语前的延迟时间
delay_on_startup_tips = 2000

#音频通道，默认为4（STREAM_ALARM）
player_stream = 4
</code></pre>

<p>预设属性完毕后，请将名为 <em>aios.properties</em> 的文件 <em>puhs</em> 到 <em>system/etc/aios</em> 目录下。</p>
<h4 id="ii_3">II.静态注册自定义命令</h4>
<p>您可以在集成 <em>SDK</em> 的工程中静态注册自定义命令。
1. 在项目的 <em>assets</em> 目录下新建 <em>custom_cmd.xml</em> 文件；
2. 填入静态注册的自定义命令，参考文本如下：</p>
<pre><code class="xml">&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;

&lt;root&gt;
    &lt;url name=&quot;/customize/video/start&quot;&gt;
        &lt;cmd name=&quot;[我想|我要|帮我](开始摄像|开始录像|启动摄像|启动录像|摄像开始|录像开始)&quot;/&gt;
        &lt;cmd name=&quot;把录像(开了|打开)&quot;/&gt;
    &lt;/url&gt;

    &lt;!--[我想|我要|帮我]，可选项 -&gt; [] --&gt;
    &lt;!--(开了|打开)，必选项 -&gt; () --&gt;
&lt;/root&gt;
</code></pre>

<ol>
<li><em>AIOSForCarSDK</em> 会在启动时主动读取该文件并完成注册。</li>
</ol>
<h3 id="_8">八、动态定制</h3>
<p><em>AIOS</em>能够将指定说法转换成指定的自定义命令，并回调预留的接口让集成者自行处理这些命令。在整个AIOS中自定义命令的解析优先级最高，如果AIOS内部命令对应的说法与自定义命令指定的说话一致，该说法将会优先解析成自定义命令。自定义命令暂时不支持携带参数。</p>
<h4 id="i_2">I .动态注册自定义命令</h4>
<ol>
<li>创建自定义命令<br />
AIOS支持一个自定义命令对应多种说法，如：</li>
</ol>
<pre><code class="java">//创建自定义命令
Command command = new Command(OPEN_AIR_CONDITION, new String[]{&quot;(开启|打开|帮我开|开下)空调&quot;});
</code></pre>

<ol>
<li>注册自定义命令（集）<br />
<em>SDK</em> 提供了多种注册自定义命令的接口，请根据具体情况选择：</li>
</ol>
<pre><code class="java">//注册单条自定义命令
public void AIOSCustomizeManager#regCommand(@NonNull Command command);
//注册单条自定义命令，并决定是否清空的所有命令
public void AIOSCustomizeManager#regCommand(@NonNull Command command, boolean isCleanCache);
//注册多条自定义命令
public void AIOSCustomizeManager#regCommands(@NonNull List&lt;Command&gt; commands);
//注册多条自定义命令，并决定是否清空的所有命令
public void AIOSCustomizeManager#regCommands(@NonNull List&lt;Command&gt; commands, boolean isCleanCache);
</code></pre>

<ol>
<li>实现并注册自定义命令监听器<br />
自定义命令监听器的回调方法中带有执行到的自定义命令串，您需要根据该参数作出对应的操作，监听器请见：</li>
</ol>
<pre><code>com.aispeech.aios.sdk.listener.AIOSCustomizeListener
</code></pre>

<p><strong>注册自定义命令监听器后</strong>，AIOS解析到任何自定义命令对应的说法，都会回调自定义命令监听器：</p>
<pre><code>//注册自定义命令监听器，以便在自定义命令生效时作自己的处理
AIOSCustomizeManager.getInstance().registerCustomizeListener(customizeListener);
</code></pre>

<ol>
<li>注销自定义命令<br />
在AIOS运行过程中，您可以根据具体情况动态地注销自定义命令。注销时根据自定义命令串（也即第一步中的 <em>/condition/open</em> ）注销，而非根据自定义命令指定的说法注销：</li>
</ol>
<pre><code class="java">//注销单条自定义命令
public void unregCommand(@NonNull String delKeyword);
//注销多条自定义命令
public void unregCommands(@NonNull String[] delKeywords);
</code></pre>

<ol>
<li>注销自定义命令监听器<br />
注销监听器之后，AIOS中仍旧保存着注册的自定义命令列表。区别在于，执行到相应操作时会出现无相应的情况，您可以在注销自定义命令监听器的同时清空所有自定义命令：</li>
</ol>
<pre><code class="java">//清空SDK注册的所有自定义命令
AIOSCustomizeManager.getInstance().cleanCommands();
//注销监听器
AIOSCustomizeManager.getInstance().unregisterCustomizeListener();
</code></pre>

<h4 id="iiapp">II.APP扫描</h4>
<p>为了减小集成者自定义命令工作量，AIOS默认会开启APP扫描，为每个APP生成“打开”“关闭”与“退出”命令。您可以通过 <em>SDK</em> 定制是否开启APP扫描功能：</p>
<pre><code class="java">//是否开启APP扫描
public void AIOSCustomizeManager#setAppScanEnable(boolean enable);
</code></pre>

<h4 id="iii_2">III.动态修改参数</h4>
<p>您可以在AIOS启动后，您依旧可以使用接口动态地修改一些参数，比如AEC状态、打断状态、录音机状态等：</p>
<pre><code class="java">//定制录音机
AIOSCustomizeManager#customizeRecorder(boolean aecEnable, boolean interruptEnable, boolean reversedChannelEnable)

//单独设置AEC状态
AIOSCustomizeManager#setAECEnabled(boolean enable)
//单独设置打断状态
AIOSCustomizeManager#setInterruptEnabled(boolean enable)
//单独设置是否开启通道反转
AIOSCustomizeManager#setReversedChannelEnabled(boolean reversedChannelEnable)
</code></pre>

<h4 id="iv">IV.定制唤醒词</h4>
<p><em>AIOS 3.0</em> 目前已经开放唤醒词的自定义，您可以通过接口定制专属的主唤醒词与丰富的快捷唤醒词：</p>
<pre><code class="java">//定制主唤醒词
AIOSCustomizeManager#setMajorWakeup(String wakeup, String pinyin, float confidence)
//定制多个主唤醒词
AIOSCustomizeManager#setMajorWakeup(List&lt;MajorWakeup&gt; wakeupList)
//定制快捷唤醒词
AIOSCustomizeManager#registerShortcutWakeups(@NonNull List&lt;ShortcutWakeup&gt; shortcutWakeups)
//定制语音启动语
AIOSCustomizeManager#setLaunchTips(@NonNull String launchTips)
//定制是否使用原生快捷唤醒词，不干扰自定义快捷唤醒词
AIOSCustomizeManager#setNativeShortcutWakeupsEnabled(boolean)
</code></pre>

<h3 id="ui">九、<em>UI</em></h3>
<blockquote>
<p>UI优先级：在导航过程中，如果想要进行听歌之类的娱乐操作时，用户更加倾向于操作完成后一段时间，<em>UI</em> 回到导航或者行车记录仪。<em>AIOS</em> 提供了 <em>UI/App</em> 优先级机制: 从高优先级的 <em>App</em> 切换到低优先级的 <em>App</em> 时，<em>AIOS</em> 会在 6s 延迟后切换回高优先级 <em>App</em>。</p>
<p>如：在导航/音乐/电台(喜马拉雅)唤醒查天气/股票/限行/路况等时，倒计时6s后会自动将之前应用从后台切换到前台。</p>
</blockquote>
<p>因为Android 5.0+对相应接口的变动，在Android 5.0+上使用UI优先级需要给 <em>Aios-adapter.apk</em> 作系统签名。您可以使用 <em>SDK</em> 提供的接口关闭UI优先级机制：</p>
<pre><code class="java">//设置UI优先级是否起效
public void AIOSUIManager#setUIPriorityEnable(boolean enable);
</code></pre>

<h4 id="i-ui">I .自定义UI优先级</h4>
<p>AIOS默认只为部分应用配置了优先级：原生支持的六种地图为第一优先级、第二优先级预留、酷我音乐与喜马拉雅为第三优先级、AIOS所有查询（路况、股票、天气与限行）类UI为第四优先级。其他应用不配置优先级的话，默认为最低优先级，低于第四优先级。</p>
<ol>
<li>定制您的应用优先级
您可以动态地定制您的应用优先级：</li>
</ol>
<pre><code class="java">//直接定制应用优先级
public void AIOSUIManager#addUIPriority(@NonNull String pkgName, int priority);
//通过JavaBean定制应用优先级
public void AIOSUIManager#addUIPriority(@NonNull UIPriority uiPriority);
//定制多个应用的优先级，并决定是否清空之前 SDK 添加的所有优先级信息
public void AIOSUIManager#addUIPriority(@NonNull List&lt;UIPriority&gt; uiPriorityList, boolean isCleanCache);
</code></pre>

<ol>
<li>监听UI优先级
如果你关心UI优先级何时执行，您可以注册UI监听器来监听。首先实现：</li>
</ol>
<pre><code class="java">com.aispeech.aios.sdk.listener.AIOSUIListener
</code></pre>

<p>然后注册：</p>
<pre><code class="java">//注册UI监听器
AIOSUIManager.getInstance().registerUiListener(this);
</code></pre>

<ol>
<li>删除UI优先级
您可以动态地删除已经配置好的UI优先级，包括AIOS预定义的部分：</li>
</ol>
<pre><code class="java">AIOSUIManager#delUIPriority(@NonNull String pkgName)；
</code></pre>

<ol>
<li>清空UI优先级
您可以一次性清空 <em>SDK</em> 注册的所有UI优先级信息：</li>
</ol>
<pre><code class="java">AIOSUIManager#cleanUIPriority();
</code></pre>

<h4 id="ii_4">II.是否显示全局的悬浮麦克风图标</h4>
<p>AIOS提供了一个全局的悬浮麦克风图标，用户可以直接点击这个悬浮图标来唤醒。这个图标默认是隐藏的，你可以将其改为显示：</p>
<pre><code class="java">AIOSUIManager#setShowGlobalMic(boolean isShow);
</code></pre>

<h4 id="iii_3">III.定制悬浮窗</h4>
<p>现在，您可以使用 <em>SDK</em> 将 <em>Android</em> 的 <em>LayoutParams</em> 对象直接传递给 <em>AIOS</em> 进行悬浮窗属性的定制：</p>
<pre><code class="java">AIOSUIManager#setLayoutParams(WindowManager.LayoutParams);
</code></pre>

<h4 id="iiii">IIII.路况显示</h4>
<p>AIOS提供路况显示悬浮窗位置自定义，传入需要显示的起始点XY位置和宽高即可：</p>
<pre><code class="java">AIOSUIManager#setTrafficOrigin(int startX, int startY, int width, int height）;
</code></pre>

<h3 id="_9">十、自定义语音播报</h3>
<p><em>AIOS</em> 提供语音播报接口，您可以在需要语音播报时调用接口播报一段文本内容或者一组文本内容。该接口内置了队列机制，支持按需播放一组文本内容：</p>
<pre><code class="java">public static void AIOSTTSManager#speak(String... texts);
</code></pre>

<h3 id="_10">十一、系统控制</h3>
<h4 id="i_3">I .响应系统控制命令</h4>
<p><strong>由于各厂商的 <em>ROM</em> 差异，有相当一部分功能 <em>AIOS</em>  无法实现。其中包括：蓝牙、<em>WiFi</em>、热点、屏幕、电子狗、行车记录仪、胎压等设置的打开与关闭，亮度与音量的调节。</strong></p>
<p>请您实现以下接口：</p>
<pre><code class="java">com.aispeech.aios.sdk.listener.AIOSSystemListener
</code></pre>

<p>其中各个方法需要使用到的取值可在以下类中找到：</p>
<pre><code class="java">//亮度控制取值类
com.aispeech.aios.common.property.SystemProperty.BrightnessProperty
//音量控制取值类
com.aispeech.aios.common.property.SystemProperty.VolumeProperty
//设置名称取值类
com.aispeech.aios.common.property.SystemProperty.CommonStateProperty
</code></pre>

<p>并通过以下接口注册系统监听器：</p>
<pre><code class="java">//注册系统监听器
AIOSSystemManager.getInstance().registerSystemListener(systemListener);
</code></pre>

<p><em>SDK</em> 提供了部分操作的实现，您可以根据实际ROM自行改写。实现代码见 <em>aios-bridge</em> 中：</p>
<pre><code class="java">com.aispeech.aios.bridge.utils.SystemDefaultUtil
</code></pre>

<h4 id="ii_5">II .发起系统控制命令</h4>
<p>目前提供ACC ON/OFF、录音机开关与重启命令：</p>
<pre><code class="java">AIOSSystemManager#setACCOn()
AIOSSystemManager#setACCOff(){
AIOSSystemManager#startRecorder(){
AIOSSystemManager#stopRecorder(){
AIOSSystemManager#restartRecorder(){
</code></pre>

<h3 id="_11">十二、状态</h3>
<p><em>AIOS</em> 内部有许多状态，可能您会关心其中一些状态。我们正在一步步对外开放这些状态，您现在可以通过实现并注册状态监听器来监听这些状态。
第一阶段开放的状态：人声检测（<em>VAD</em>）音量大小，倾听状态、识别状态、录音机状态、AIOS状态、TTS播报状态、语音识别文本、语音反馈文本。</p>
<p>状态监听器见：</p>
<pre><code class="java">com.aispeech.aios.sdk.listener.AIOSStatusListener
</code></pre>

<p>注册状态监听器代码如下：</p>
<pre><code class="java">//注册状态监听器
AIOSStatusManager.getInstance().registerStatusListener(statusListener);
</code></pre>

<h3 id="_12">十三、快捷唤醒</h3>
<p>导航/微信/音乐/系统领域支持快捷唤醒操作，无需使用主、副唤醒词即可轻松使用。详情见 <a href="#appendix2">附录2</a></p></div>
        </div>

        <footer class="col-md-12">
            <hr>
            
            <center>Documentation built with <a href="http://www.mkdocs.org/">MkDocs</a>.</center>
        </footer>

        <script src="../js/jquery-1.10.2.min.js"></script>
        <script src="../js/bootstrap-3.0.3.min.js"></script>
        <script src="../js/highlight.pack.js"></script>
        <script>var base_url = '..';</script>
        <script data-main="../mkdocs/js/search.js" src="../mkdocs/js/require.js"></script>
        <script src="../js/base.js"></script>

        <div class="modal" id="mkdocs_search_modal" tabindex="-1" role="dialog" aria-labelledby="Search Modal" aria-hidden="true">
            <div class="modal-dialog">
                <div class="modal-content">
                    <div class="modal-header">
                        <button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">&times;</span><span class="sr-only">Close</span></button>
                        <h4 class="modal-title" id="exampleModalLabel">Search</h4>
                    </div>
                    <div class="modal-body">
                        <p>
                            From here you can search these documents. Enter
                            your search terms below.
                        </p>
                        <form role="form">
                            <div class="form-group">
                                <input type="text" class="form-control" placeholder="Search..." id="mkdocs-search-query">
                            </div>
                        </form>
                        <div id="mkdocs-search-results"></div>
                    </div>
                    <div class="modal-footer">
                    </div>
                </div>
            </div>
        </div>
    </body>
</html>